package pe.com.casadesign.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import pe.com.casadesign.dao.GuiaDAO;
import pe.com.casadesign.dao.SolicitudDAO;
import pe.com.casadesign.dao.VentaDAO;
import pe.com.casadesign.dao.ItemDAO;
import pe.com.casadesign.dao.PrestamoDAO;
import pe.com.casadesign.dao.MantenimientoDAO;
import pe.com.casadesign.dao.TransporteDAO;
import pe.com.casadesign.dao.OrdenCompraDAO;
import pe.com.casadesign.domain.Bulto;
import pe.com.casadesign.domain.Guia;
import pe.com.casadesign.domain.ItemComponente;
import pe.com.casadesign.domain.LineaDetalleBulto;
import pe.com.casadesign.domain.LineaGuiaBulto;
import pe.com.casadesign.domain.ListaLineaDetalleBulto;
import pe.com.casadesign.domain.ListaLineaGuiaBulto;
import pe.com.casadesign.domain.ListaSolicitud;
import pe.com.casadesign.domain.OperacionError;
import pe.com.casadesign.domain.Venta;
import pe.com.casadesign.domain.Item;
import pe.com.casadesign.domain.LineaGuia;
import pe.com.casadesign.domain.LineaGuiaItem;
import pe.com.casadesign.domain.Mantenimiento;
import pe.com.casadesign.domain.Solicitud;
import pe.com.casadesign.domain.Prestamo;
import pe.com.casadesign.domain.Transporte;
import pe.com.casadesign.domain.OrdenCompra;
import pe.com.casadesign.domain.OperacionResultado;
import pe.com.casadesign.service.GuiaService;
import pe.com.casadesign.domain.ListaGuia;
import pe.com.casadesign.service.util.Constantes;


/**
 * Implementacion de GuiaService.
 * 
 * @author Pedro Vera
 * 
 */
@Service
public class GuiaServiceImpl implements GuiaService {
	private static final Logger logger = LoggerFactory
			.getLogger(GuiaServiceImpl.class);

	@Autowired
	private GuiaDAO guiaDAO;
	@Autowired
	private VentaDAO ventaDAO;
	@Autowired
	private ItemDAO itemDAO;
	@Autowired
	private PrestamoDAO prestamoDAO;
	@Autowired
	private MantenimientoDAO mantenimientoDAO;
	@Autowired
	private SolicitudDAO solicitudDAO;
	@Autowired
	private TransporteDAO transporteDAO;
	@Autowired
	private OrdenCompraDAO ordenCompraDAO;

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public OperacionResultado registrarGuia(Guia guia) {
		boolean resultado = guiaDAO.registrarGuia(guia);

		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guia.getCodGuia()));
		operacionResultado.setEsOK(resultado ? Constantes.SI : Constantes.NO);

		return operacionResultado;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public OperacionResultado registrarGuiaImportacion(Guia guia) {
		boolean resultado = guiaDAO.registrarGuiaImportacion(guia);

		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guia.getCodGuia()));
		operacionResultado.setEsOK(resultado ? Constantes.SI : Constantes.NO);

		return operacionResultado;
	}
	
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public OperacionResultado registrarGuiaOrdenCompra(Guia guia) {
		boolean resultado = guiaDAO.registrarGuiaOrdenCompra(guia) > 0;

		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guia.getCodGuia()));
		operacionResultado.setEsOK(resultado ? Constantes.SI : Constantes.NO);

		return operacionResultado;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public OperacionResultado registrarGuiaDetalleBulto(Guia guia) {
		boolean resultado = guiaDAO.registrarGuiaDetalleBulto(guia) > 0;

		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guia.getCodGuia()));
		operacionResultado.setEsOK(resultado ? Constantes.SI : Constantes.NO);

		return operacionResultado;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public OperacionResultado registrarGuiaDocumento(Guia guia) {
		boolean resultado = guiaDAO.registrarGuiaDocumento(guia);
		if (guia.getVenta() != null) {
			// actualizar venta (cambio de estado de la venta)
			int modificarVenta = ventaDAO.modificarVenta(guia.getVenta());
		}
		
		if (guia.getPrestamo() != null) {
			// actualizar el estado del prestamo (cambio de estado del prestamo)
            int modificarPrestamo = prestamoDAO.modificarPrestamo(guia.getPrestamo());
		}
		
		if (guia.getMantenimiento() != null){
			//actualizar el estado del mantenimiento
			int modificarMantenimiento = mantenimientoDAO.modificarMantenimiento(guia.getMantenimiento());
		}
		
		if (guia.getSolicitud() != null){
			//actualizar el estado de la transferencia
			int modificarSolicitud = solicitudDAO.actualizarEstadoSolicitud(guia.getSolicitud());
		}
		
		// Actualizar estado de item actualizarEstadoItem (item)
		for (LineaGuia lineaGuia : guia.getListaLineaGuia().getLista()) {
			for (LineaGuiaItem lineaGuiaItem : lineaGuia.getListaLineaGuiaItem().getLista()) {
				int resultado_item = itemDAO.actualizarEstadoItem(lineaGuiaItem.getItem());
			}
		}

		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guia.getCodGuia()));
		operacionResultado.setEsOK(resultado ? Constantes.SI : Constantes.NO);

		return operacionResultado;
	}
	
	@Override
	public Guia obtenerGuia(Guia guia){
		Guia guiaResultado = guiaDAO.obtenerGuia(guia);
		
		if(guiaResultado != null) {
			// Obteniendo los componentes de los items
			for (LineaGuia lineaGuia : guiaResultado.getListaLineaGuia().getLista()){
				for(LineaGuiaItem lineaGuiaItem : lineaGuia.getListaLineaGuiaItem().getLista()) {
					if(lineaGuiaItem.getItem().getProducto().getComponentes().equals(Constantes.SI)) {
						Item itemTemporal = itemDAO.obtenerItem(lineaGuiaItem.getItem());
						lineaGuiaItem.getItem().setListaItemComponente(itemTemporal.getListaItemComponente());
					}
				}
			}
		}
		
		if (String.valueOf(guiaResultado.getMantenimiento().getCodMantenimiento()) != null |
		    guiaResultado.getMantenimiento().getCodMantenimiento() != 0 ){
			Mantenimiento mantenimiento = mantenimientoDAO.obtenerMantenimiento(guiaResultado.getMantenimiento());
			guiaResultado.setMantenimiento(mantenimiento);
		}
		
		if (String.valueOf(guiaResultado.getVenta().getCodVenta()) != null |
			guiaResultado.getVenta().getCodVenta() != 0){
			Venta venta = ventaDAO.obtenerVenta(guiaResultado.getVenta());
			guiaResultado.setVenta(venta);
		}
		
		if (String.valueOf(guiaResultado.getSolicitud().getCodSolicitud()) != null |
			guiaResultado.getSolicitud().getCodSolicitud() != 0	){
			Solicitud solicitud = solicitudDAO.obtenerSolicitudItem(guiaResultado.getSolicitud());
			guiaResultado.setSolicitud(solicitud);
		}
		
		if (String.valueOf(guiaResultado.getPrestamo().getCodPrestamo()) != null |
			guiaResultado.getPrestamo().getCodPrestamo() != 0){
			Prestamo prestamo = prestamoDAO.obtenerPrestamo(guiaResultado.getPrestamo());
			guiaResultado.setPrestamo(prestamo);
		}
		
		if (String.valueOf(guiaResultado.getTransporte().getCodTransporte()) != null |
			guiaResultado.getTransporte().getCodTransporte() != 0){
			Transporte transporte = transporteDAO.obtenerTransporte(guiaResultado.getTransporte());
			guiaResultado.setTransporte(transporte);
		}
		
		return guiaResultado;
	}
	
	@Override
	public Guia obtenerGuiaCodGuia(Guia guia){
		Guia guiaResultado = guiaDAO.obtenerGuia(guia);
		
		if (String.valueOf(guiaResultado.getMantenimiento().getCodMantenimiento()) != null |
			    guiaResultado.getMantenimiento().getCodMantenimiento() != 0 ){
				Mantenimiento mantenimiento = mantenimientoDAO.obtenerMantenimiento(guiaResultado.getMantenimiento());
				guiaResultado.setMantenimiento(mantenimiento);
			}
			
			if (String.valueOf(guiaResultado.getVenta().getCodVenta()) != null |
				guiaResultado.getVenta().getCodVenta() != 0){
				Venta venta = ventaDAO.obtenerVenta(guiaResultado.getVenta());
				guiaResultado.setVenta(venta);
			}
			
			if (String.valueOf(guiaResultado.getSolicitud().getCodSolicitud()) != null |
				guiaResultado.getSolicitud().getCodSolicitud() != 0	){
				Solicitud solicitud = solicitudDAO.obtenerSolicitudItem(guiaResultado.getSolicitud());
				guiaResultado.setSolicitud(solicitud);
			}
			
			if (String.valueOf(guiaResultado.getPrestamo().getCodPrestamo()) != null |
				guiaResultado.getPrestamo().getCodPrestamo() != 0){
				Prestamo prestamo = prestamoDAO.obtenerPrestamo(guiaResultado.getPrestamo());
				guiaResultado.setPrestamo(prestamo);
			}
			
			if (String.valueOf(guiaResultado.getTransporte().getCodTransporte()) != null |
				guiaResultado.getTransporte().getCodTransporte() != 0){
				Transporte transporte = transporteDAO.obtenerTransporte(guiaResultado.getTransporte());
				guiaResultado.setTransporte(transporte);
			}
		
		return guiaResultado;
	}
	
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public OperacionResultado modificarGuia(Guia guia) {
		boolean resultado = guiaDAO.modificarGuia(guia) > 0;

		if (guia.getSolicitud() != null) {
			// actualizar el estado de la transferencia
			int modificarSolicitud = solicitudDAO.actualizarEstadoSolicitud(guia.getSolicitud());
		}

		// Actualizar estado de item actualizarEstadoItem (item)
		for (LineaGuia lineaGuia : guia.getListaLineaGuia().getLista()) {
			for (LineaGuiaItem lineaGuiaItem : lineaGuia.getListaLineaGuiaItem().getLista()) {
				int resultado_item = itemDAO.modificarItem(lineaGuiaItem.getItem());
			}
		}

		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guia.getCodGuia()));
		operacionResultado.setEsOK(resultado ? Constantes.SI : Constantes.NO);

		return operacionResultado;

	}
	
	@Override
	public Guia obtenerGuiaOrdenCompra(Guia guia){
		Guia guiaResultado = guiaDAO.obtenerGuiaOrdenCompra(guia);
		
		return guiaResultado;
	}
	
	
	@Override
	public OperacionResultado validarGuia(Guia guia){
		boolean resultado = guiaDAO.validarGuia(guia) > 0;
		
		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guia.getCodGuia()));
		operacionResultado.setEsOK(resultado ? Constantes.SI : Constantes.NO);

		return operacionResultado;
	}
	
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public OperacionResultado registrarGuiaDetalleActualizaItem(Guia guia) {
		int limpiar = guiaDAO.limpiarGuiaDetalle(guia);
		
		boolean resultado = guiaDAO.registrarGuiaDetalle(guia, true) > 0;

		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guia.getCodGuia()));
		operacionResultado.setEsOK(resultado ? Constantes.SI : Constantes.NO);

		return operacionResultado;
	}
	
	
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public OperacionResultado registrarGuiaDetalleCreaItem(Guia guia) {
		int limpiar = guiaDAO.limpiarGuiaDetalle(guia);
		
		boolean resultado = guiaDAO.registrarGuiaDetalle(guia, false) > 0;

		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guia.getCodGuia()));
		operacionResultado.setEsOK(resultado ? Constantes.SI : Constantes.NO);

		return operacionResultado;
	}
	
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public OperacionResultado actualizarGuia (Guia guiaActual, Guia guiaNueva){
		boolean resultado1 = guiaDAO.registrarGuiaDocumento(guiaNueva);
		
        int limpiar = guiaDAO.limpiarGuiaDetalle(guiaActual);
		
		boolean resultado2 = guiaDAO.registrarGuiaDetalle(guiaActual, true) > 0;

		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guiaNueva.getCodGuia()));
		operacionResultado.setEsOK((resultado1&&resultado2) ? Constantes.SI : Constantes.NO);

		return operacionResultado;
		
	}
	
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public OperacionResultado registrarGuiaProcesoImportacion(Guia guia) {

		boolean resultadoGuiaImportacion = true;
		boolean resultadoGuiaOrdenCompra = false;
		boolean resultadoGuiaDetalleBulto = false;
		
		
		boolean resultadovalidarguia = guiaDAO.validarGuia(guia) > 0;

		if (!resultadovalidarguia) {
			resultadoGuiaImportacion = guiaDAO.registrarGuiaImportacion(guia);
		}
		if (resultadoGuiaImportacion) {
			 resultadoGuiaOrdenCompra = guiaDAO.registrarGuiaOrdenCompra(guia) > 0;
			if (resultadoGuiaOrdenCompra) {
				resultadoGuiaDetalleBulto = guiaDAO.registrarGuiaDetalleBulto(guia) > 0;
								
			}
		}
		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guia.getCodGuia()));
		operacionResultado.setEsOK((resultadoGuiaImportacion && resultadoGuiaOrdenCompra
						&& resultadoGuiaDetalleBulto) ? Constantes.SI: Constantes.NO);

		return operacionResultado;
	}
	
	@Override
	public ListaGuia listarPrestamoGuia(Guia guia) {
		return guiaDAO.listarPrestamoGuia(guia);
	}
	
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public OperacionResultado registrarGuiaDocumentoBulto(Guia guia) {
		boolean resultado = guiaDAO.registrarGuiaDocumentoBulto(guia);
		
		if (guia.getSolicitud() != null){
			//actualizar el estado de la transferencia
			int modificarSolicitud = solicitudDAO.actualizarEstadoSolicitud(guia.getSolicitud());
		}
	   
		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guia.getCodGuia()));
		operacionResultado.setEsOK(resultado ? Constantes.SI : Constantes.NO);

		return operacionResultado;
	}
	
	@Override
	public OperacionResultado procesarGuiaDocumentoBulto(Guia guia) {
		OperacionError operacionError = null;
		OperacionResultado operacionResultado = null;
		boolean resultado = false;
		
		// Instanciando operacionResultado
		operacionResultado = new OperacionResultado();
		operacionResultado.setEsOK(Constantes.NO);
		
		// Obteniendo la lista de lineas del inventario
		ListaLineaGuiaBulto listaLineaGuiaBulto = guia.getListaLineaGuiaBulto();
				
		for (LineaGuiaBulto lineaGuiaBulto : listaLineaGuiaBulto.getLista())
		{		
			  // Registrar bulto en el inventario
				resultado = guiaDAO.registrarGuiaBultoDetalle(lineaGuiaBulto);
				operacionResultado .setCodigoGenerado(String.valueOf(lineaGuiaBulto.getCodGuia()));
				operacionResultado .setEsOK(resultado ? Constantes.SI : Constantes.NO);
		
		}
				
 		   
		return operacionResultado;
	}
	
	
	@Override
	public Guia obtenerGuiaDocumentoBulto(Guia guia) {
		return guiaDAO.obtenerGuiaDocumentoBulto(guia);
	}

	@Override
	@Transactional (propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
	public OperacionResultado actualizarEstadoGuia(Guia guia) {
		boolean resultado = guiaDAO.actualizarEstadoGuia(guia)>0;
		
		OperacionResultado operacionResultado = new OperacionResultado();
		operacionResultado.setCodigoGenerado(String.valueOf(guia.getCodGuia()));
		operacionResultado.setEsOK(resultado?Constantes.SI:Constantes.NO);
		
		return operacionResultado;
	}
	
}

